<?php

namespace App\Http\Controllers;

use App\Models\PictureLive;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Intervention\Image\ImageManagerStatic as Image;

/**
 * composer require intervention/image
 * 
 * 图片直播文件上传类
 */
class PictureLiveUploadsFileController extends Controller
{

    //允许文件上传的key
    protected $allow_file_name_arr = ['picture_live'];

    protected $need_thumb_file_name_arr = ['picture_live']; //需要生成缩略图的key

    /**
     * 定义图片上传公共方法           (单文件与多文件都可以(多文件上传不生成缩略图)  暂不支持多文件上传)
     * @param file 文件名   根据每个方法要求不同，传不同名称   默认file 
     *                     固定参数   picture_live  前台活动报名，上传图片   不需生成缩略图   最大1M
     * 
     * 
     * @param act_id 活动id 
     */
    public function commonUpload(Request $request)
    {
        $act_id = $request->act_id;
        $file_name = array_keys($_FILES);
        //   dd([request()->file($file_name[0])->getMimeType(),request()->file($file_name[0])->getClientMimeType(),request()->file($file_name[0])->getClientOriginalExtension()]);

        if (empty($act_id))  return ['code' => 201, 'msg' => '活动id不能为空'];
        if (empty($file_name))  return ['code' => 201, 'msg' => '上传文件不能为空'];
        if (!in_array($file_name[0], $this->allow_file_name_arr)) return ['code' => 201, 'msg' => '上传文件名错误'];

        $pictureLiveModel = new PictureLive();
        $pictureLive_info = $pictureLiveModel->apiIsCanUploads($act_id);
        if (is_string($pictureLive_info)) {
            return ['code' => 201, 'msg' => $pictureLive_info];
        }

        //验证文件类型和大小
        $file_validate = $this->fileValidate($request, $file_name[0]);
        if ($file_validate !== true) {
            return ['code' => 201, 'msg' => $file_validate];
        }

        $foldername = $file_name[0] . '/' . date('Y-m-d'); //$file_name.'/'.date('Y-m-d')  存放路径，按日志存储
        $file = $request->file($file_name)->store($foldername);

        $file_addr = public_path('uploads') . '/' . $file; //图片地址

        if ($file) {
            $data['img'] = substr($file, 0, 1) == '/' ? substr($file, 1, strlen($file)) : $file; //去掉第一个 斜线

            //获取水印图片
            $watermark_type = !empty($pictureLive_info['watermark_type']) ? $pictureLive_info['watermark_type'] : 1;
            $watermark_img = !empty($pictureLive_info['watermark_img']) ? $pictureLive_info['watermark_img'] : null;
            $watermark_text = !empty($pictureLive_info['watermark_text']) ? $pictureLive_info['watermark_text'] : null;
            //原图添加水印
            $img = $this->getThumbImg($file_addr, $file, '.', false, null, null, $watermark_type, $watermark_img, $watermark_text); //只添加水印
            $watermark_type = $img ? 0 : $watermark_type; //如果原图添加好水印，就不用在添加了
            //是否需要生成缩略图
            if (in_array($file_name[0], $this->need_thumb_file_name_arr)) {
                $thumb_img1 = $this->getThumbImg($file_addr, $file, '_cover.', false, 0, 20, $watermark_type, $watermark_img, $watermark_type); //只压缩质量 20，前面已经添加了水印
                $thumb_img2 = $this->getThumbImg($file_addr, $file, '_thumb.', true, 0, 90, $watermark_type, $watermark_img, $watermark_type); //按比例裁剪图片大小，压缩质量 60
                if ($thumb_img1 && $thumb_img2) {
                    $data['cover'] = $thumb_img1['thumb_img_name']; //列表显示，为最小的图
                    $data['thumb_img'] = $thumb_img2['thumb_img_name']; //详情显示，只压缩质量的图
                    $data['width'] = $thumb_img2['small_img_width'];
                    $data['height'] = $thumb_img2['small_img_height'];
                    $data['ratio'] = $img['small_img_width'] . 'x' . $img['small_img_height'];
                    $data['size'] = $_FILES[$file_name[0]]['size'];
                } else {
                    $data['thumb_img'] = substr($file, 0, 1) == '/' ? substr($file, 1, strlen($file)) : $file; //去掉第一个 斜线
                    $data['cover'] = null;
                    $data['width'] = null;
                    $data['height'] = null;
                    $data['ratio'] = null;
                    $data['size'] = null;
                }
            }

            return ['code' => 200, 'msg' => '上传成功', 'content' => $data];
        } else {
            return ['code' => 404, 'msg' => '未找到资源', 'data' => ''];
        }
    }


    /**
     * 获取图片封面（缩略图）
     * @param $file_addr 图片路径  ,数据库存放路径
     * @param $file 原图片返回到前端的地址
     * @param $is_ratio 是否按比例压缩   true 是  false 不压缩
     * @param $ratio 压缩比例   0 默认压缩比例  其他 就是按比例压缩，比如传 0.5 就在原来基础上压缩一半
     * @param $quality 压缩质量   90为和原图一致   1 ~ 100 中间  100图片变大了
   //  * @param $watermark 是否添加水印  true false 

     * @param $watermark_type  水印类型  0 无水印 1、默认图片水印 2 自定义图片水印  3 自定义文字水印 
     * @param $watermark_img 水印图片
     * @param $watermark_text 水印文字
     * 
     * @param $new_file_name 新图片名，必须包含点 ·  最后会在原基础上，进行替换
     */
    public function getThumbImg($file_addr, $file, $new_file_name = null, $is_ratio = true, $ratio = 0, $quality = null, $watermark_type = null, $watermark_img = null, $watermark_text = null)
    {

        ini_set('memory_limit', '1024M'); //临时加大内存，否则在生成缩略图时可能没反应 Image::make($file_addr) 时；

        $img_info = @getimagesize($file_addr);
        // if(!$img_info) return 'default/default_production_cover.png';//图片不存在直接返回false
        if (!$img_info) return ''; //图片不存在直接返回'' ; 使用默认图片

        $width = $img_info[0];
        $height = $img_info[1];
        $small_img_width = $width;
        $small_img_height = $height;

        $quality = $quality ? $quality : null; //压缩质量,90
        $thumb_img = Image::make($file_addr);

        if ($is_ratio) {
            if ($ratio) {
                $small_img_width = round($width * $ratio, 5); //压缩宽度
                $small_img_height = round($height * $ratio, 5); //压缩高度

                $thumb_img = $thumb_img->resize($small_img_width, $small_img_height);
            } else {
                $small_img_width = $width < 500 ? (int)$width : 500; //缩略图宽
                $ratio = round($small_img_width / $width, 5); //计算压缩比
                $small_img_height = round($height * $ratio, 5); //高度按宽度比例压缩

                $thumb_img = $thumb_img->resize($small_img_width, $small_img_height);
            }
        }

        //是否添加水印
        if ($watermark_type == 1 || $watermark_type == 2) {
            //根据原图片宽度，调整水印大小
            if ($width < 1000) {
                //插入水印, 水印位置在原图片的右下角, 距离下边距 10 像素, 距离右边距 15 像素
                $watermark_img = $watermark_img ? str_replace('.', '2.', $watermark_img) : 'default/default_watermark_img2.png';
                $watermark_x = 15;
                $watermark_y = 10;
            } elseif ($width >= 1000 && $width < 2000) {
                //插入水印, 水印位置在原图片的右下角, 距离下边距 10 像素, 距离右边距 15 像素
                $watermark_img = $watermark_img ? str_replace('.', '1.', $watermark_img) : 'default/default_watermark_img1.png';
                $watermark_x = 30;
                $watermark_y = 20;
            } elseif ($width >= 2000) {
                //插入水印, 水印位置在原图片的右下角, 距离下边距 10 像素, 距离右边距 15 像素
                $watermark_img = $watermark_img ? $watermark_img : 'default/default_watermark_img.png'; //原图最大，2最小
                $watermark_x = 50;
                $watermark_y = 35;
            }
            $watermark_img = public_path('uploads') . '/' . $watermark_img;
            $thumb_img = $thumb_img->insert($watermark_img, 'bottom-right', $watermark_x, $watermark_y);
            // $thumb_img = $thumb_img->text('我就是来看看水印加字好看不.', 120, 100); //添加文字水印
        } elseif ($watermark_type == 3) {
            //调整字体大小
            if ($width < 1000) {
                $font_size = 20;
            } elseif ($width >= 1000 && $width < 2000) {
                $font_size = 40;
            } elseif ($width >= 2000) {
                $font_size = 60;
            }
            // 检测水印颜色  
            $text_color = $this->detectWatermarkColor($file_addr);
            // 在图片上添加文本  
            $thumb_img = $this->addWatermarkWithText($thumb_img, null, null, $watermark_text, 'bottom-right', $font_size, $text_color);
        }

        //将处理后的图片重新保存到其他路径
        $new_file_name = $new_file_name ? $new_file_name : '_thumb.';
        if (stripos($new_file_name, '.') === false) {
            return ''; //生成失败，返回默认图
        }
        $thumb_img_addr = str_replace('.', $new_file_name, $file_addr);
        $thumb_img = $thumb_img->save($thumb_img_addr, $quality); // 保存图片，并设置质量压缩为60   save 第二个参数为压缩质量
        if (is_object($thumb_img)) {
            $thumb_img_name = str_replace('.', $new_file_name, $file);
            return ['thumb_img_name' => $thumb_img_name, 'small_img_width' => $small_img_width, 'small_img_height' => $small_img_height];
        }
        return ''; //生成失败，返回默认图
    }



    /**
     * 添加文字水印
     * @param image_obj 图片对象
     * @param file_addr 图片地址  与对象 2选一 
     * @param output_path 返回图片地址  如果传了则需要输出图片，无则直接返回对象即可
     */
    public function addWatermarkWithText($image_obj, $file_addr, $output_path, $watermark_text, $position = 'bottom-right', $font_size = 16, $text_color = 'rgba(255, 255, 255, 0.5)', $font_path = null)
    {
        if (empty($image_obj) && empty($file_addr)) {
            return false;
        }

        $image = $image_obj ? $image_obj : Image::make($file_addr);

        //获取字体路径
        $font_path = !empty($font_path) ? $font_path : public_path('font/MSYH.ttf');

        // 使用imagettfbbox()计算文字的边界框
        $bbox = imagettfbbox($font_size, 0, $font_path, $watermark_text);
        // 计算文字宽度
        $text_width = $bbox[2] - $bbox[0];
        $textHeight = abs($bbox[5] - $bbox[3] + $bbox[1]);

        $text_strlen = strlen($watermark_text);

        if ($text_strlen > 30) {
            $text_width  = $text_width  - $text_strlen * 1.5; //多减去一部分 
        } elseif ($text_strlen > 15) {
            $text_width  = $text_width  - $text_strlen; //多减去10  
        } elseif ($text_strlen < 8) {
            $text_width  = $text_width  + $text_strlen * 1.5; //加上一部分 
        }

        switch ($position) {
            case 'top-left':
                $x = 30;
                $y = 30;
                break;
            case 'top-right':
                $x = $image->width() - $text_width - 10;
                $y = 30;
                break;
            case 'bottom-left':
                $x = 30;
                $y = $image->height() - $textHeight - 10;
                break;
            case 'bottom-right':
                $x = $image->width() - $text_width - 10;
                $y = $image->height() - $textHeight - 10;
                break;
                // 可以添加更多位置...  
            default:
                $x = 30;
                $y = 30;
        }

        // 在图片上添加文本  
        $image->text($watermark_text, $x, $y, function ($font) use ($font_size, $font_path, $text_color) {
            $font->file($font_path); // 如果有自定义字体  
            $font->size($font_size);
            $font->color($text_color);
        });

        // 保存图片  
        if ($output_path) {
            $thumb_img = $image->save($output_path);
            if (is_object($thumb_img)) {
                return true;
            }
        }

        return $image; //不保存直接返回图片对象
    }

    /**
     * 自动识别图片颜色
     */
    public function detectWatermarkColor($file_addr = null)
    {
        $image = Image::make($file_addr); //这里不能传递对象

        try {
            $image = $image->greyscale();

            // 计算平均亮度（简单示例，仅取一个像素）  
            $pixel = $image->pickColor(1, 1, 'array'); // 你可以选择一个代表性的像素，或者计算所有像素的平均值  
            $brightness = array_sum($pixel) / count($pixel); // 假设pixel是一个RGB数组  
            // 根据平均亮度确定水印颜色  
            return $brightness > 128 ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)'; // 使用RGBA格式，并添加透明度（可选）  
        } catch (\Exception $e) {
            // 处理异常，例如记录日志或返回默认颜色  
            return 'rgba(255, 255, 255, 0.5)'; // 默认使用白色半透明水印  
        }
    }



    /**
     * 文件验证
     */
    public function fileValidate($request, $file = 'file')
    {
        $file_type = $this->getFileTypeAndSize($file);

        $validator = Validator::make($request->file(), [
            $file => 'required|file|max:' . $file_type['size'] . '|mimes:' . $file_type['ext'] . '|dimensions:min_width=300,min_height=300',
        ], [
            //验证是否存在文件
            $file . '.required' => '文件不能为空',
            //验证是否为文件
            $file . '.file' => '请确认你的文件格式',
            //验证文件上传大小
            $file . '.max' => '文件大小不符合要求',
            //验证上传文件格式
            $file . '.mimes' => '请确认上传文件后缀' . $file_type['ext'],
            $file . '.dimensions' => '请确认上传文件尺寸比例必须大于300x300',
        ]);
        if ($validator->fails()) { //如果有错误
            // return $validator->errors(); //返回得到错误
            return join('|', $validator->errors()->toArray()[$file]); //获取所有的错误，用 | 拼接
        }

        return true;
    }

    /**
     * 根据文件名，定义上传允许的后缀 和 文件大小
     * https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types   mimes mimetypes  对照表
     */
    public function getFileTypeAndSize($file_name)
    {
        switch ($file_name) {
            case 'picture_live':
                $file_type = ['size' => 2 * 1024, 'ext' => 'jpg,png,jpeg']; //2M   size 单位 kb  tp框架单位为 b
                break;
            default:
                $file_type = ['size' => 1 * 1024, 'ext' => 'jpg,png,jpeg'];
                break;
        }
        return $file_type;
    }
}
